package cn.itcast.bos.service.take_delivery.impl;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.QueryStringQueryBuilder.Operator;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bos.dao.index.WayBillIndexRepository;
import cn.itcast.bos.dao.take_delivery.WayBillRepository;
import cn.itcast.bos.domain.take_delivery.WayBill;
import cn.itcast.bos.service.take_delivery.WayBillService;

@Service
@Transactional
public class WayBillServiceImpl implements WayBillService {
	@Autowired
	private WayBillRepository wayBillRepository;
	@Autowired
	private WayBillIndexRepository wayBillIndexRepository;

	@Override
	public void save(WayBill wayBill) {
		WayBill persistWayBill = wayBillRepository.findByWayBillNum(wayBill.getWayBillNum());
		if (persistWayBill == null) {
			// 修改运单的状态为1,“未发货”
			wayBill.setSignStatus(1);
			// 之前的运单不存在,执行保存
			wayBillRepository.save(wayBill);
			// 创建运单的索引在elasticsearch服务器中
			wayBillIndexRepository.save(wayBill);
		} else {
			// 之前的运单存在,执行更新
			// 获得之前已经存在的运单id
			Integer id = persistWayBill.getId();
			// 将要保存的运单信息 拷贝到之前存在的运单中
			BeanUtils.copyProperties(wayBill, persistWayBill);
			// 重新给之前存在运单赋予id
			persistWayBill.setId(id);
			// 保存之前存在的运单实现订单的更新
			wayBillRepository.save(persistWayBill);
			// 更新在elasticsearch服务器中的索引
			wayBillIndexRepository.save(persistWayBill);
		}
	}

	@Override
	public Page<WayBill> pageQuery(WayBill wayBill, Pageable pageable) {
		// 判断wayBill中是否封装查询条件
		// 没有封装查询条件
		if (StringUtils.isBlank(wayBill.getWayBillNum()) && StringUtils.isBlank(wayBill.getSendAddress())
				&& StringUtils.isBlank(wayBill.getRecAddress()) && StringUtils.isBlank(wayBill.getSendProNum())
				&& (wayBill.getSignStatus() == null || wayBill.getSignStatus() == 0)) {
			return wayBillRepository.findAll(pageable);
		} else {
			// 封装了查询条件
			// 布尔查询,来组合查询条件,must同时成立,should有一个成立,must not 同时不成立
			BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
			if (StringUtils.isNotBlank(wayBill.getWayBillNum())) {
				QueryBuilder termQueryBuilder = new TermQueryBuilder("wayBillNum", wayBill.getWayBillNum());
				boolQueryBuilder.must(termQueryBuilder);
			}
			if (StringUtils.isNotBlank(wayBill.getSendAddress())) {
				// 情况一：搜索条件是词条的一部分,模糊查询
				QueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder("sendAddress",
						"*" + wayBill.getSendAddress() + "*");
				// 情况二：搜索条件是多个词条的组合
				QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(wayBill.getSendAddress())
						.field("sendAddress").defaultOperator(Operator.AND);
				BoolQueryBuilder boolQuery = new BoolQueryBuilder();
				boolQuery.should(wildcardQueryBuilder);
				boolQuery.should(queryStringQueryBuilder);
				boolQueryBuilder.must(boolQuery);
			}
			if (StringUtils.isNotBlank(wayBill.getRecAddress())) {
				// 情况一：搜索条件是词条的一部分,模糊查询
				QueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder("recAddress",
						"*" + wayBill.getRecAddress() + "*");
				// 情况二：搜索条件是多个词条的组合
				QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(wayBill.getRecAddress())
						.field("recAddress").defaultOperator(Operator.AND);
				BoolQueryBuilder boolQuery = new BoolQueryBuilder();
				boolQuery.should(wildcardQueryBuilder);
				boolQuery.should(queryStringQueryBuilder);
				boolQueryBuilder.must(boolQuery);
			}
			if (StringUtils.isNotBlank(wayBill.getSendProNum())) {
				QueryBuilder termQueryBuilder = new TermQueryBuilder("sendProNum", wayBill.getSendProNum());
				boolQueryBuilder.must(termQueryBuilder);
			}
			if (wayBill.getSignStatus() != null && wayBill.getSignStatus() != 0) {
				QueryBuilder termQueryBuilder = new TermQueryBuilder("signStatus", wayBill.getSignStatus());
				boolQueryBuilder.must(termQueryBuilder);
			}
			SearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder).setPageable(pageable);

			return wayBillIndexRepository.search(nativeSearchQuery);
		}

	}

	@Override
	public WayBill findByWayBillNum(String wayBillNum) {

		return wayBillRepository.findByWayBillNum(wayBillNum);
	}
}
